package com.fz.security.provider;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fz.common.GlobalAll;
import com.fz.common.ResultCode;
import com.fz.entity.member.Member;
import com.fz.mapper.member.MemberMapper;
import com.fz.security.AuthExceptionDto;
import com.fz.security.tokens.MobilePwdAuthenticationToken;
import com.fz.utils.JacksonUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;
@Component
public class MobilePwdAuthenticationProvider implements AuthenticationProvider {
    @Resource
    private MemberMapper memberMapper;

    /**
     * @方法描述: 验证手机号密码登录
     * @参数:
     * @返回值:
     * @创建人: I am God
     * @创建时间:: 2021/2/24
     */
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //获取手机号
        String mobile = (String) authentication.getPrincipal();
        //获取密码
        String password = (String) authentication.getCredentials();

        //查询该手机号用户是否存在
        LambdaQueryWrapper<Member> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Member::getMobilePhone,mobile);
        Member member = memberMapper.selectOne(lambdaQueryWrapper);
        if(null == member){
            throw new BadCredentialsException(JacksonUtils.obj2String(new AuthExceptionDto(ResultCode.NO_EXIT_USER.getResultCode(), ResultCode.NO_EXIT_USER.getMessage())));
        }else{
            //如果存在用户，则判断密码是否正确
            //验证用户名密码是否正确
            //首先通过前端传过来的公钥加密的密码进行解密，获取明文
            RSA rsa = new RSA(GlobalAll.RSA_PRIVATE_KEY,null);
            String jmpassword = new String(rsa.decrypt(password, KeyType.PrivateKey));
            //通过明文与数据库的加密的密码进行比对
            PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            boolean flag = passwordEncoder.matches(jmpassword,member.getPassword());
            if(flag == false){
                throw new BadCredentialsException(JacksonUtils.obj2String(new AuthExceptionDto(ResultCode.PWD_ERROR.getResultCode(), ResultCode.PWD_ERROR.getMessage())));
            }
        }
        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(member.getMobilePhone(), password, listUserGrantedAuthorities(member.getUid()));
        result.setDetails(member);
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (MobilePwdAuthenticationToken.class.isAssignableFrom(authentication));
    }

    private Set<GrantedAuthority> listUserGrantedAuthorities(Integer uid) {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        return authorities;
    }
}
